/*
 * Copyright (C) The Apache Software Foundation. All rights reserved.
 *
 * This software is published under the terms of the Apache Software License
 * version 1.1, a copy of which has been included with this distribution in
 * the LICENSE file.
 */
package ranab.server.ftp.gui;


import java.util.Vector;

import java.awt.Component;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

import ranab.gui.GuiUtils;
import ranab.server.ftp.FtpConfig;
import ranab.server.ftp.FtpServer;


/**
 * This is FTP user interface tree structure.
 * It looks like:
 * <pre>
 *   FTP
 *    |
 *    +-- User (User management)
 *    |
 *    +-- Ip (IP restrictions)
 *    |
 *    +-- Connection (Connection monitor)
 *    |
 *    +-- Spy (Spy user activities)
 *    |
 *    +-- Statistics (Global statistics)
 *    |
 *    +-- Upload (File upload statistics)
 *    |
 *    +-- Download (File download statistics)
 *    |
 *    +-- Delete (File deletion statistics)
 *    |
 *    +-- About (Ftp server summary)
 * </pre>
 */

public
class FtpTree extends JTree implements TreeModel {
    
    public final static String[] CHILDREN = {
        "User",
        "IP",
        "Connection",
        "Spy",
        "Statistics",
        "Upload",
        "Download",
        "Delete",
        "About"    
    }; 
    
    private Vector mListenrList;
    
    private Component mTopFrame;
    private FtpRootPanel mRootPanel;
    private PluginPanel[] mPluginPanels;
    
    
    /**
     * create this tree model
     */
    public FtpTree() {
        mListenrList = new Vector();
        setModel(this);
        
        setSelectionPath(new TreePath(FtpServer.NAME));
        putClientProperty("JTree.lineStyle", "Angled");
        
        DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
        renderer.setLeafIcon(null);
        renderer.setOpenIcon(null);
        renderer.setClosedIcon(null);
        setCellRenderer(renderer);
        
        mRootPanel = new FtpRootPanel(this);
        initPlugins();
    }
    
    /**
     * Initialize all plugin panels
     */
    private void initPlugins() {
        mPluginPanels = new PluginPanel[CHILDREN.length];
        
        mPluginPanels[0] = new FtpUserPanel(this);
        mPluginPanels[1] = new FtpIpPanel(this);
        mPluginPanels[2] = new FtpConnectionPanel(this);
        mPluginPanels[3] = new FtpSpyContainerPanel(this);
        mPluginPanels[4] = new FtpStatisticsPanel(this);
        mPluginPanels[5] = new FtpFilePanel(this, ((FtpStatisticsPanel)mPluginPanels[4]).getUploadModel(),   "Uploaded Files");
        mPluginPanels[6] = new FtpFilePanel(this, ((FtpStatisticsPanel)mPluginPanels[4]).getDownloadModel(), "Downloaded Files");
        mPluginPanels[7] = new FtpFilePanel(this, ((FtpStatisticsPanel)mPluginPanels[4]).getDeleteModel(),   "Deleted Files");
        mPluginPanels[8] = new FtpAboutPanel(this);
    }
    

    /**
     * get root object
     */
    public Object getRoot() {
        return FtpServer.NAME;
    }

    /** 
     * get child object
     */
    public Object getChild(Object parent, int index) {
        return CHILDREN[index];
    } 

    /**
     * get child count
     */
    public int getChildCount(Object parent) {
        if(parent.equals(FtpServer.NAME)) {
            return CHILDREN.length;
        }
        return 0;
    }

    /**
     * is a leaf or node
     */
    public boolean isLeaf(Object node) {
       return !node.equals(FtpServer.NAME);
    }

    /**
     * get child index
     */
    public int getIndexOfChild(Object parent, Object child) {
       int childIdx = -1;
       for(int i=0; i<CHILDREN.length; i++) {
           if(CHILDREN[i].equals(child)) {
               childIdx = i;
               break;
           }
       }
       return childIdx;
    }

    /**
     * Object changed. In our case it is not possible - so igmore it.
     */
    public void valueForPathChanged(TreePath path, Object newValue) {
    }

    /**
     * add a listener
     */
    public void addTreeModelListener(TreeModelListener l) {
        mListenrList.add(l);
    }

    /**
     * remove a listener
     */
    public void removeTreeModelListener(TreeModelListener l) {
        mListenrList.remove(l);
    }
    
    /**
     * Refresh all panels
     */
    public void refresh(FtpConfig config) {
        for(int i=0; i<mPluginPanels.length; i++) {
            mPluginPanels[i].refresh(config);
        }
    }
    
    /**
     * Get top frame.
     */
    public FtpRootPanel getRootPanel() {
        return mRootPanel;
    }
    
    
    /**
     * Get top frame
     */    
    public Component getTopFrame() {
        if(mTopFrame == null) {
            mTopFrame = GuiUtils.getFrame(this);
        }
        return mTopFrame;
    }


    /**
     * Get plugin panel.
     */
    public PluginPanel getPluginPanel(String panelName) {
        PluginPanel panel = null;
        for(int i=0; i<CHILDREN.length; i++) {
            if (CHILDREN[i].equals(panelName)) {
                panel = mPluginPanels[i];
                break;
            }
        }
        return panel;
    }
     
     
    /**
     * Get the selected panel.
     */ 
    public JPanel getSelectedPanel() {
        Object node = getSelectionPath().getLastPathComponent();
        
        JPanel dispPane = null;
        if(getRoot().equals(node)) {
            dispPane = mRootPanel;
        }
        else {
            dispPane = getPluginPanel(node.toString());
            if ( (dispPane == null) || (!dispPane.isDisplayable()) ) {
                dispPane = mRootPanel;
            }
        }
        
        return dispPane;
    } 
     
}
